package com.fbs.job.admin.service.impl;

import com.fbs.job.admin.core.entity.FbsJobActuator;
import com.fbs.job.admin.core.entity.FbsJobLogReport;
import com.fbs.job.admin.core.entity.FbsJobUser;
import com.fbs.job.admin.core.util.CookieUtil;
import com.fbs.job.admin.core.util.DateTool;
import com.fbs.job.admin.core.util.JacksonUtil;
import com.fbs.job.admin.mapper.FbsJobActuatorMapper;
import com.fbs.job.admin.mapper.FbsJobInfoMapper;
import com.fbs.job.admin.mapper.FbsJobLogReportMapper;
import com.fbs.job.admin.mapper.JobUserMapper;
import com.fbs.job.admin.service.JobUserService;
import com.fbs.job.core.model.ResultT;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigInteger;
import java.util.*;

@Service
public class JobUserServiceImpl implements JobUserService {


    @Resource
    private JobUserMapper jobUserMapper;

    @Resource
    private FbsJobInfoMapper jobInfoMapper;

    @Resource
    private FbsJobActuatorMapper jobActuatorMapper;
    @Resource
    private FbsJobLogReportMapper jobLogReportMapper;
    /**
     * logout
     *
     * @param request
     * @param response
     */
    public ResultT<String> logout(HttpServletRequest request, HttpServletResponse response){
        CookieUtil.remove(request, response, LOGIN_IDENTITY_KEY);
        return ResultT.success(null);
    }

    @Override
    public Map<String, Object> dashboardInfo() {
        int jobInfoCount = jobInfoMapper.findAllCount();
        int jobLogCount = 0;
        FbsJobLogReport fbsJobLogReport = jobLogReportMapper.queryLogReportTotal();
        if (fbsJobLogReport != null) {
            jobLogCount = fbsJobLogReport.getRunningCount() + fbsJobLogReport.getSucCount() + fbsJobLogReport.getFailCount();
        }

        // executor count
        Set<String> executorAddressSet = new HashSet<String>();
        List<FbsJobActuator> groupList = jobActuatorMapper.findAll();

        if (groupList!=null && !groupList.isEmpty()) {
            for (FbsJobActuator group: groupList) {
                if (group.getRegistryList()!=null && !group.getRegistryList().isEmpty()) {
                    executorAddressSet.addAll(group.getRegistryList());
                }
            }
        }

        int executorCount = executorAddressSet.size();



        Map<String, Object> dashboardMap = new HashMap<String, Object>();
        dashboardMap.put("jobInfoCount", jobInfoCount);
        dashboardMap.put("jobLogCount", jobLogCount);
        dashboardMap.put("executorCount", executorCount);
        return dashboardMap;
    }

    @Override
    public ResultT<Map<String, Object>> chartInfo(Date startDate, Date endDate) {
        // process
        List<String> triggerDayList = new ArrayList<String>();
        List<Integer> triggerDayCountRunningList = new ArrayList<Integer>();
        List<Integer> triggerDayCountSucList = new ArrayList<Integer>();
        List<Integer> triggerDayCountFailList = new ArrayList<Integer>();
        int triggerCountRunningTotal = 0;
        int triggerCountSucTotal = 0;
        int triggerCountFailTotal = 0;

        List<FbsJobLogReport> logReportList = jobLogReportMapper.queryLogReport(startDate, endDate);

        if (logReportList!=null && logReportList.size()>0) {
            for (FbsJobLogReport item: logReportList) {
                String day = DateTool.getYMD(item.getTriggerDay());
                int triggerDayCountRunning = item.getRunningCount();
                int triggerDayCountSuc = item.getSucCount();
                int triggerDayCountFail = item.getFailCount();

                triggerDayList.add(day);
                triggerDayCountRunningList.add(triggerDayCountRunning);
                triggerDayCountSucList.add(triggerDayCountSuc);
                triggerDayCountFailList.add(triggerDayCountFail);

                triggerCountRunningTotal += triggerDayCountRunning;
                triggerCountSucTotal += triggerDayCountSuc;
                triggerCountFailTotal += triggerDayCountFail;
            }
        } else {
            for (int i = -6; i <= 0; i++) {
                triggerDayList.add(DateTool.getYMD(DateUtils.addDays(new Date(), i)));
                triggerDayCountRunningList.add(0);
                triggerDayCountSucList.add(0);
                triggerDayCountFailList.add(0);
            }
        }

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("triggerDayList", triggerDayList);
        result.put("triggerDayCountRunningList", triggerDayCountRunningList);
        result.put("triggerDayCountSucList", triggerDayCountSucList);
        result.put("triggerDayCountFailList", triggerDayCountFailList);

        result.put("triggerCountRunningTotal", triggerCountRunningTotal);
        result.put("triggerCountSucTotal", triggerCountSucTotal);
        result.put("triggerCountFailTotal", triggerCountFailTotal);

        return new ResultT<>(result);
    }

    @Override
    public FbsJobUser ifLogin(HttpServletRequest request, HttpServletResponse response) {
        String cookieToken = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
        if (cookieToken != null) {
            FbsJobUser cookieUser = null;
            try {
                cookieUser = parseToken(cookieToken);
            } catch (Exception e) {
                logout(request, response);
            }
            if (cookieUser != null) {
                FbsJobUser dbUser = jobUserMapper.getByUserName(cookieUser.getUsername());
                if (dbUser != null) {
                    if (cookieUser.getPassword().equals(dbUser.getPassword())) {
                        return dbUser;
                    }
                }
            }
        }
        return null;
    }
    private String makeToken(FbsJobUser fbsJobUser){
        String tokenJson = JacksonUtil.writeValueAsString(fbsJobUser);
        String tokenHex = new BigInteger(tokenJson.getBytes()).toString(16);
        return tokenHex;
    }
    private FbsJobUser parseToken(String tokenHex){
        FbsJobUser fbsJobUser = null;
        if (tokenHex != null) {
            String tokenJson = new String(new BigInteger(tokenHex, 16).toByteArray());      // username_password(md5)
            fbsJobUser = JacksonUtil.readValue(tokenJson, FbsJobUser.class);
        }
        return fbsJobUser;
    }

    @Override
    public ResultT login(HttpServletRequest request, HttpServletResponse response, String username, String password, boolean ifRemember) {
        // param
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)){
            return ResultT.error("账号或密码为空");
        }

        // valid passowrd
        FbsJobUser fbsJobUser = jobUserMapper.getByUserName(username);
        if (fbsJobUser == null) {
            return ResultT.error("账号或密码错误");
        }

        String passwordMd5 = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!passwordMd5.equals(fbsJobUser.getPassword())) {
            return ResultT.error("账号或密码错误");
        }
        String loginToken = makeToken(fbsJobUser);

        // do login
        CookieUtil.set(response, LOGIN_IDENTITY_KEY, loginToken, ifRemember);
        return ResultT.success(null);
    }
}
